import * as THREE from 'three'
import {
  CSS2DRenderer,
  CSS2DObject,
} from 'three/addons/renderers/CSS2DRenderer.js'

// 排名前三的飞船加分时候的特写镜头
export const showCloseupForTopThree = () => {
  // 首先按照分数对行星排序，分数从高到低
  const sortedList = this.list
    .filter((planet) => planet.name !== '太阳')
    .sort((a, b) => b.score - a.score)
  const topThree = sortedList.slice(0, 3) // 前三名行星

  if (topThree.length > 0) {
    const topPlanet = topThree[0] // 获取第一名行星
    const spaceship = this.scene.getObjectByName(topPlanet.name) // 获取飞船对象

    if (spaceship) {
      // 执行摄像机特写动画
      this.animateCameraCloseup(spaceship)
      // 增加相机的缩放效果--执行摄像机特写动画  222可以干掉
      function animateCameraZoom(camera, targetFov, duration = 2) {
        TweenLite.to(camera, duration, {
          fov: targetFov,
          onUpdate: () => {
            camera.updateProjectionMatrix()
          },
        })
      }

      // 在飞船特写时调用
      animateCameraZoom(camera, 40) // 将视角缩小到 40 度
    }
  }
}
// 排名前三的飞船加分时候的特写镜头
export const animateCameraCloseup = (target) => {
  const originalPosition = {
    x: camera.position.x,
    y: camera.position.y,
    z: camera.position.z,
  } // 记录原始视角位置
  const targetPosition = new THREE.Vector3() // 用于存储飞船的位置
  target.getWorldPosition(targetPosition) // 获取飞船的世界坐标

  // 将摄像机缓动到飞船附近形成特写
  TweenLite.to(camera.position, 2, {
    x: targetPosition.x + 220, // 使摄像机稍微远离飞船
    y: targetPosition.y + 220,
    z: targetPosition.z + 80,
    ease: 'power1.inOut',
    onUpdate: () => {
      camera.lookAt(targetPosition) // 保持摄像机看向飞船
    },
    onComplete: () => {
      // 3秒后返回原视角
      setTimeout(() => {
        this.animateCameraToOriginal(originalPosition)
      }, 2000) // 保持特写3秒
    },
  })
}
export const animateCameraToOriginal = (originalPosition) => {
  // 将摄像机缓动返回原视角
  TweenLite.to(camera.position, 2, {
    x: originalPosition.x,
    y: originalPosition.y,
    z: originalPosition.z,
    ease: 'power1.inOut',
    onUpdate: () => {
      camera.lookAt(new THREE.Vector3(0, 0, 0)) // 返回时对准中心点（比如太阳）
    },
  })
}
// 初始化动画，先显示太阳再绕远处飞船转一圈
export const initCameraAnimation = (camera) => {
  let startTime = null
  const that = this

  // 定义相机的初始状态（太阳中心）和最终状态（轨道最远处）
  const initialPosition = { x: 0, y: 0, z: 0 } // 初始相机位置：太阳中心
  const finalPosition = { x: 1000, y: 500, z: 1000 } // 轨道最远处
  const originalPosition = { x: 235, y: 735, z: 1000 } // 最终恢复位置

  const duration = 5000 // 动画时长，5秒
  const orbitRadius = 800 // 定义轨道半径
  // 动画的核心函数
  function animateCamera(timestamp) {
    if (!startTime) startTime = timestamp
    const elapsedTime = timestamp - startTime
    const progress = Math.min(elapsedTime / duration, 1) // 计算动画进度

    // 第一阶段：从太阳中心移动到轨道最远处
    if (progress < 0.5) {
      const t = progress * 2 // 时间进度比例，0 到 1
      camera.position.x =
        initialPosition.x + t * (finalPosition.x - initialPosition.x)
      camera.position.y =
        initialPosition.y + t * (finalPosition.y - initialPosition.y)
      camera.position.z =
        initialPosition.z + t * (finalPosition.z - initialPosition.z)
      camera.lookAt(new THREE.Vector3(0, 0, 0)) // 始终对准太阳
    }
    // 第二阶段：轨道飞船上方绕一圈
    else if (progress >= 0.5 && progress < 0.8) {
      const t = (progress - 0.5) * 2 * Math.PI // 时间进度比例，0 到 2π，表示旋转角度
      camera.position.x = orbitRadius * Math.cos(t)
      camera.position.z = orbitRadius * Math.sin(t)
      camera.position.y = 600 // 固定高度，保持在飞船上方
      camera.lookAt(new THREE.Vector3(0, 0, 0)) // 相机始终看向太阳
    }
    // 第三阶段：返回初始视角
    else {
      const t = (progress - 0.8) / 0.2 // 返回的进度，0 到 1
      camera.position.x =
        finalPosition.x + t * (originalPosition.x - finalPosition.x)
      camera.position.y =
        finalPosition.y + t * (originalPosition.y - finalPosition.y)
      camera.position.z =
        finalPosition.z + t * (originalPosition.z - finalPosition.z)
      camera.lookAt(new THREE.Vector3(0, 0, 0)) // 始终对准太阳
    }

    // 渲染场景

    if (progress < 1) {
      requestAnimationFrame(animateCamera) // 如果动画没有结束，继续下一帧
    }
  }

  requestAnimationFrame(animateCamera) // 启动动画
}

// 创建显示分数标签的方法
export const showScoreLabel = (spaceship, score, name) => {
  const div = document.createElement('div')
  div.className = 'score-label'
  div.innerHTML = `${name}+${score}分`

  // 设置样式
  div.style.color = 'white'
  div.style.fontSize = '24px'
  div.style.fontWeight = 'bold'
  div.style.textShadow =
    '0 0 10px rgba(255, 255, 0, 0.8), 0 0 20px rgba(255, 255, 0, 1)'
  div.style.padding = '5px 10px'
  div.style.borderRadius = '10px'
  div.style.background =
    'linear-gradient(135deg, rgba(255, 150, 0, 0.8), rgba(255, 215, 0, 1))'
  div.style.boxShadow = '0 0 30px rgba(255, 215, 0, 0.6)'
  div.style.transition = 'all 0.5s ease-out'
  div.style.transform = 'scale(1)'
  div.style.opacity = '1'

  const label = new CSS2DObject(div)
  label.position.set(0, spaceship.scale.y + 15, 0)
  spaceship.add(label)

  let startTime = null

  // 使用 requestAnimationFrame 实现淡出动画
  function fadeOut(timestamp) {
    if (!startTime) startTime = timestamp
    const progress = timestamp - startTime
    const opacity = Math.max(1 - progress / 3000, 0) // 2秒内将透明度从1变为0
    div.style.opacity = opacity

    if (opacity > 0) {
      requestAnimationFrame(fadeOut) // 继续执行下一帧
    } else {
      spaceship.remove(label) // 完全透明后移除标签
      div.remove() // 从DOM中移除
    }
  }

  requestAnimationFrame(fadeOut) // 启动动画
}

// 创建动画轨道
export const createFixedOrbits = (scene) => {
  const numOrbits = 5 // 轨道数量
  const minRadius = 100 // 最小轨道半径
  const gap = 150 // 每条轨道的间距
  let outerCircleMesh = null // 保存最外层的圆环
  let innerCircleMesh = null // 保存最内层的圆环

  for (let i = 0; i < numOrbits; i++) {
    const radius = minRadius + i * gap
    const arc = new THREE.ArcCurve(0, 0, radius, 0, 2 * Math.PI, true)
    const points = arc.getPoints(100)
    const lineGeometry = new THREE.BufferGeometry().setFromPoints(points)

    // 判断是否是最外侧轨道或最内侧轨道
    let material
    if (i === numOrbits - 1 || i === 0 ) {
      // 最外侧或最内侧
      const textureLoader = new THREE.TextureLoader()
      const texture = textureLoader.load('/public/img/yuanhuan5.png') // 加载圆环纹理

      material = new THREE.MeshBasicMaterial({
        map: texture,
        transparent: true, // 使纹理的透明部分生效
        opacity: 1, // 设置不透明度
        side: THREE.DoubleSide, // 双面显示
        depthWrite: false, // 禁止深度写入，避免闪烁问题
      })
      const circleGeometry = new THREE.CircleGeometry(radius + 10, 64) // 创建一个圆形几何体
      const circleMesh = new THREE.Mesh(circleGeometry, material)
      circleMesh.rotation.x = Math.PI / 2 // 将圆形平面与水平面对齐

      if (i === numOrbits - 1) {
        outerCircleMesh = circleMesh // 最外侧圆环
      } else {
        innerCircleMesh = circleMesh // 最内侧圆环
      }
      scene.add(circleMesh) // 添加带有纹理的圆环作为轨道
    } else if(i === 2){
  // 最外侧或最内侧
  const textureLoader = new THREE.TextureLoader()
  const texture = textureLoader.load('/public/img/m6.png') // 加载圆环纹理

  material = new THREE.MeshBasicMaterial({
    map: texture,
    transparent: true, // 使纹理的透明部分生效
    opacity: 1, // 设置不透明度
    side: THREE.DoubleSide, // 双面显示
    depthWrite: false, // 禁止深度写入，避免闪烁问题
  })
  const circleGeometry = new THREE.CircleGeometry(radius + 10, 64) // 创建一个圆形几何体
  const circleMesh = new THREE.Mesh(circleGeometry, material)
  circleMesh.rotation.x = Math.PI / 2 // 将圆形平面与水平面对齐

  if (i === numOrbits - 1) {
    outerCircleMesh = circleMesh // 最外侧圆环
  } else {
    innerCircleMesh = circleMesh // 最内侧圆环
  }
  scene.add(circleMesh) // 添加带有纹理的圆环作为轨道
    }
    else {
      // material = new THREE.LineBasicMaterial({
      //   color: 0x0f4984,
      //   transparent: true,
      //   opacity: 0.5,
      // })
            // 最外侧或最内侧
            const textureLoader = new THREE.TextureLoader()
            const texture = textureLoader.load('/public/img/m5.png') // 加载圆环纹理
      
            material = new THREE.MeshBasicMaterial({
              map: texture,
              transparent: true, // 使纹理的透明部分生效
              opacity: 1, // 设置不透明度
              side: THREE.DoubleSide, // 双面显示
              depthWrite: false, // 禁止深度写入，避免闪烁问题
            })
            const circleGeometry = new THREE.CircleGeometry(radius + 10, 64) // 创建一个圆形几何体
            const circleMesh = new THREE.Mesh(circleGeometry, material)
            circleMesh.rotation.x = Math.PI / 2 // 将圆形平面与水平面对齐
      
            if (i === numOrbits - 1) {
              outerCircleMesh = circleMesh // 最外侧圆环
            } else {
              innerCircleMesh = circleMesh // 最内侧圆环
            }
            scene.add(circleMesh) // 添加带有纹理的圆环作为轨道
    }

    const line = new THREE.LineLoop(lineGeometry, material)
    line.rotateX(Math.PI / 2)
    scene.add(line) // 添加轨道线到场景
  }

  // 将 outerCircleMesh 和 innerCircleMesh 返回以供后续使用
  return { outerCircleMesh, innerCircleMesh }
}

    // 创建宇宙(球形宇宙) ---TODO 这个解决模糊问题
    export const  createUniverse = (scene)=>{
      // 加载纹理
      const textureLoader = new THREE.TextureLoader()
      const texture = textureLoader.load('/public/img/universe.jpg')

      // 创建球体几何体，翻转法线让球体内部可见
      const geometry = new THREE.SphereGeometry(7000, 64, 64)
      geometry.scale(-1, 1, 1) // 反转几何体，让背景朝内渲染

      // 创建 Shader 材质
      const material = new THREE.ShaderMaterial({
        uniforms: {
          texture1: { value: texture }, // 将加载的纹理传递给着色器
        },
        vertexShader: `
      varying vec2 vUv;
      void main() {
        vUv = uv; // 将 UV 坐标传递给片段着色器
        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
      }
    `,
        fragmentShader: `
      uniform sampler2D texture1; // 纹理采样器
      varying vec2 vUv; // 接收顶点着色器传递的 UV 坐标
      void main() {
        gl_FragColor = texture2D(texture1, vUv); // 根据 UV 坐标获取纹理颜色
      }
    `,
        side: THREE.DoubleSide, // 显示几何体的两面
      })

      // 创建球体网格并添加到场景中
      const sphere = new THREE.Mesh(geometry, material)
      // 调整背景球体的默认角度
      sphere.rotation.x = Math.PI / 2 // 围绕 X 轴旋转 30 度
      sphere.rotation.y = Math.PI / 1 // 围绕 Y 轴旋转 45 度
      sphere.rotation.z = Math.PI / 3 // 围绕 Z 轴旋转 22.5 度

      scene.add(sphere)
    }